<?php
class UnitTestCase_Unfuddle_Model_Ticket extends UnitTestCase_Unfuddle {

    protected $_defaultTimezone;
    
    protected $_ticketXML;
    
    public function setUp() {
    
        $this->_defaultTimezone = date_default_timezone_get();
        $this->_ticketXML = file_get_contents(TESTCASE_PATH . '/files/xml/ticket.xml.txt');
    
    }
    
    public function tearDown() {
    
        // set the default timezone back to what it was
        // I don't think this is necessary but it can't hurt
        date_default_timezone_set($this->_defaultTimezone);
    
    }
    
    public function testConstruct() {
    
        $ticket = new Unfuddle_Model_Ticket(array());
        $this->assertIsA($ticket, 'Unfuddle_Model_Abstract');
    
    }
    
    public function testUnknownPropertyThrowsException() {
    
        $this->expectException(new Unfuddle_Model_Exception("Attempting to set non-existent 'foo' property for the ticket model."));
        $ticket = new Unfuddle_Model_Ticket(array(
            'assignee-id' => 1,
            'description' => 'A description',
            'foo' => 'baz',
        ));
    
    }
    
    public function testValueNotInSetThrowsException() {
    
        $this->expectException(new Unfuddle_Model_Exception("Priority property must be one of: 1, 2, 3, 4, 5"));
        $ticket = new Unfuddle_Model_Ticket(array(
            'assignee-id' => 1,
            'description' => 'A descriptive description',
            'priority' => 'foo',
        ));
    
    }
    
    public function testGetProperty() {
    
        $ticket = new Unfuddle_Model_Ticket(array('status' => 'new', 'summary' => 'A new ticket'));
        $this->assertEqual($ticket->getProperty('status'), 'new');
    
    }
    
    public function testGetNonExistentPropertyThrowsException() {
    
        $this->expectException(new Unfuddle_Model_Exception("Attempting to retrieve non-existent 'foo' property for the ticket model."));
        $ticket = new Unfuddle_Model_Ticket(array('status' => 'new', 'summary' => 'A new ticket'));
        $foo = $ticket->getProperty('foo');
    
    }
    
    public function testSetPropertyConvertsValuesAppropriately() {
    
        $ticket = new Unfuddle_Model_Ticket(array(
            'due-on' => 'April 23, 2011', // date
            'created-at' => 'January 12, 2011 6:16pm', // datetime
            'assignee-id' => '1', // integer
            'hours-estimate-current' => '5.5', // float
            'summary' => 'A new ticket', // text (string)
        ));
        $this->assertEqual($ticket->getProperty('due-on'), '2011-04-23');
        // Because datetime values are stored in UTC time, the date/time will be
        // offset by the amount of hours difference between the user's timezone
        // and GMT (UTC time). This functionality is more extensively tested below.
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-13T02:16:00Z');
        $this->assertIdentical($ticket->getProperty('assignee-id'), 1);
        $this->assertIdentical($ticket->getProperty('hours-estimate-current'), 5.5);
        $this->assertIdentical($ticket->getProperty('summary'), 'A new ticket');
    
    }
    
    public function testDateTimeConvertsToUTC() {
    
        date_default_timezone_set('America/Los_Angeles'); // GMT - 8hrs
        // GMT should be 8 hours ahead of this...
        $ticket = new Unfuddle_Model_Ticket(array('created-at' => 'January 13, 2011 8:30am'));
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-13T16:30:00Z');
        date_default_timezone_set('US/Eastern'); // GMT - 5hrs
        // GMT should be 5 hours ahead of this...
        $ticket = new Unfuddle_Model_Ticket(array('created-at' => 'January 13, 2011 1:00am'));
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-13T06:00:00Z');
        date_default_timezone_set('Europe/Budapest'); // GMT + 1hrs
        // GMT should be 1 hours behind this...
        $ticket = new Unfuddle_Model_Ticket(array('created-at' => 'January 13, 2011 10:00am'));
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-13T09:00:00Z');
        date_default_timezone_set('Asia/Shanghai'); // GMT + 8hrs
        // GMT should be 8 hours behind this...
        $ticket = new Unfuddle_Model_Ticket(array('created-at' => 'January 13, 2011 10:00pm'));
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-13T14:00:00Z');
    
    }
    
    /**
     * Were a user to create a ticket like this, unaware that due-on does not
     * support time (only date), their intention would be that the ticket should
     * be due on Jan 13. But were it converted to UTC time, the date would 
     * read Jan 14, at 7:00am. This test is to make sure that the date isn't
     * inadvertently converted to Jan 14th in cases such as this.
     */
    public function testDateNotInadvertentlyConvertedToUTC() {
    
        date_default_timezone_set('America/Los_Angeles');
        $ticket = new Unfuddle_Model_Ticket(array('due-on' => 'January 13, 2011 11:00pm'));
        $this->assertEqual($ticket->getProperty('due-on'), '2011-01-13');
    
    }
    
    public function testCreateNewTicketFromXML() {
    
        $xml = $this->_ticketXML;
        $ticket = Unfuddle_Model_Ticket::fromXml($xml);
        $this->assertEqual($ticket->getProperty('assignee-id'), 1);
        $this->assertEqual($ticket->getProperty('summary'), 'Fix the index creation');
        $this->assertEqual($ticket->getProperty('created-at'), '2011-01-11T01:15:13Z');
    
    }
    
    public function testRequiredFields() {
    
        $ticket = new Unfuddle_Model_Ticket(array(
            // 'summary' => 'A new ticket',
            // 'priority' => 5,
            'description' => 'This ticket only has a description. Let\'s see how that works out...'
        ));
        $this->assertFalse($ticket->isValid());
        $this->assertEqual($ticket->getErrors(), array(
            'summary' => 'The summary property cannot be blank.',
            'priority' => 'The priority property cannot be blank.',
        ));
    
    }

}